package com.bocloud.cmp.driver.providers.vmware;

import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.bocloud.cmp.driver.providers.ServerDriver;
import com.bocloud.cmp.driver.utils.AssembleTools;
import com.bocloud.cmp.enums.VMStatus;
import com.bocloud.cmp.model.NetcardOperation;
import com.bocloud.cmp.model.OSMigrateModel;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.SnapshotModel;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.utils.KeyGenerator;
import com.bocloud.common.utils.ListTool;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecFileOperation;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDisk;
import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
import com.vmware.vim25.VirtualE1000;
import com.vmware.vim25.VirtualE1000e;
import com.vmware.vim25.VirtualEthernetCard;
import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
import com.vmware.vim25.VirtualMachineCloneSpec;
import com.vmware.vim25.VirtualMachineConfigSpec;
import com.vmware.vim25.VirtualMachineMovePriority;
import com.vmware.vim25.VirtualMachinePowerState;
import com.vmware.vim25.VirtualMachineRelocateSpec;
import com.vmware.vim25.VirtualMachineSnapshotInfo;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.VirtualMachineToolsStatus;
import com.vmware.vim25.VirtualPCNet32;
import com.vmware.vim25.VirtualVmxnet2;
import com.vmware.vim25.VirtualVmxnet3;
import com.vmware.vim25.mo.ComputeResource;
import com.vmware.vim25.mo.Datacenter;
import com.vmware.vim25.mo.Datastore;
import com.vmware.vim25.mo.DistributedVirtualPortgroup;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.Network;
import com.vmware.vim25.mo.Task;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VmwareDistributedVirtualSwitch;

/**
 * vmware虚拟机操作接口实现类
 * 
 * @author weiwei
 *
 */
public class VmwareServerDriver extends VmwareDriver implements ServerDriver {

	private static Logger logger = LoggerFactory.getLogger(VmwareServerDriver.class);

	public VmwareServerDriver() {
		super();
	}

	public VmwareServerDriver(String endpoint, String username, String password) {
		super(endpoint, username, password);
	}

	@Override
	public BsmResult create(ServerModel server) {
		try {
			ManagedEntity datacenter = new InventoryNavigator(this.getRootFolder()).searchManagedEntity(DC,
					server.getVdcName());
			if (null == datacenter) {
				logger.error("数据中心不存在！");
				return new BsmResult(false, "数据中心不存在！");
			}
			Datacenter center = (Datacenter) datacenter;
			InventoryNavigator navigator = new InventoryNavigator(center);
			VirtualMachine template = (VirtualMachine) navigator.searchManagedEntity(VM, server.getTemplate());
			ComputeResource computeResource = null;
			if (StringUtils.isEmpty(server.getClusterName())) {
				computeResource = (ComputeResource) navigator.searchManagedEntity(CR, server.getHostName());
			} else {
				computeResource = (ComputeResource) navigator.searchManagedEntity(CR, server.getClusterName());
			}
			HostSystem hostSystem = (HostSystem) navigator.searchManagedEntity("HostSystem", server.getHostName());
			Datastore datastore = (Datastore) navigator.searchManagedEntity(DT, server.getDatastore());
			VirtualMachine tempVm = (VirtualMachine) navigator.searchManagedEntity(VM, server.getName());
			if (null != tempVm) {
				logger.error("虚机 [{}]名称已经存在！", server.getName());
				return new BsmResult(false, "创建虚拟机失败：名称已经存在！");
			}
			if (null == template) {
				logger.error("模板不存在！");
				return new BsmResult(false, "创建虚拟机失败：模板不存在！");
			}
			if (null == hostSystem) {
				logger.error("宿主机不存在！");
				return new BsmResult(false, "创建虚拟机失败：宿主机不存在！");
			}
			if (null == datastore) {
				// logger.warn("数据存储不存在！采用本地存储");
				Datastore[] datastores = hostSystem.getDatastores();
				if (null == datastores || datastores.length <= 0) {
					logger.error("本地存储不存在！");
					return new BsmResult(false, "创建虚拟机失败：本地存储不存在！");
				}
				for (Datastore store : datastores) {
					if (store.getSummary().getName().equalsIgnoreCase(server.getDatastore())) {
						datastore = store;
						break;
					}
				}
			}
			if (null == datastore) {
				logger.warn("数据存储不存在！");
				return new BsmResult(false, "创建虚机失败：数据存储不存在！");
			}

			// locate配置
			VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
			if (computeResource.getResourcePool() != null) {
				relocateSpec.setPool(computeResource.getResourcePool().getMOR());
			}
			relocateSpec.setDatastore(datastore.getMOR());
			relocateSpec.setHost(hostSystem.getMOR());

			// 虚拟机配置信息
			VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
			// 设置CPU核数
			configSpec.setNumCPUs(server.getCpu());
			// 设置内存大小
			configSpec.setMemoryMB(new Long(server.getMemory()));
			// 设置虚拟机名称
			configSpec.setName(server.getName());
			// 设置虚拟机描述
			if (!StringUtils.isEmpty(server.getRemark())) {
				configSpec.setAnnotation(server.getRemark());
			}

			// 网络设备配置
			VirtualDevice[] devices = template.getConfig().getHardware().getDevice();
			Map<String, VirtualDevice> deviceMap = Maps.newHashMap();
			if (null != devices) {
				for (VirtualDevice device : devices) {
					deviceMap.put(device.getDeviceInfo().getLabel(), device);
				}
			}
			// 配置网络设备设置
			List<VirtualDeviceConfigSpec> specs = Lists.newArrayList();
			operateNetSpec(navigator, server, specs, template);
			if (!ListTool.isEmpty(specs)) {
				VirtualDeviceConfigSpec[] specArray = new VirtualDeviceConfigSpec[specs.size()];
				configSpec.setDeviceChange(specs.toArray(specArray));
			}
			// 虚拟机克隆配置
			VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
			cloneSpec.setLocation(relocateSpec);
			cloneSpec.setPowerOn(true);
			cloneSpec.setTemplate(false);
			cloneSpec.setConfig(configSpec);

			// 模板克隆虚拟机任务
			Task task = template.cloneVM_Task((Folder) template.getParent(), server.getName(), cloneSpec);
			if (task.waitForTask().equals(Task.SUCCESS)) {
				VirtualMachine machine = (VirtualMachine) new InventoryNavigator(this.getRootFolder())
						.searchManagedEntity(VM, server.getName());
				ServerModel model = null;
				VirtualMachineToolsStatus toolsStatus = machine.getGuest().getToolsStatus();
				if (null == toolsStatus || "toolsNotInstalled".equals(toolsStatus.toString())) {
					model = AssembleTools.getInstance().convertServer(machine);
				} else {
					boolean flag = true;
					Long start = System.currentTimeMillis();
					while (flag) {
						// 超时和延时
						if (System.currentTimeMillis() - start > 1000 * 60) {
							flag = false;
							model = AssembleTools.getInstance().convertServer(machine);
						} else {
							if ("toolsOk".equals(machine.getGuest().getToolsStatus().toString())) {
								flag = false;
								model = AssembleTools.getInstance().convertServer(machine);
							} else {
								Thread.sleep(5000);
								machine = (VirtualMachine) new InventoryNavigator(this.getRootFolder())
										.searchManagedEntity(VM, server.getName());
							}
						}
					}
				}
				if (null == model) {
					machine = (VirtualMachine) new InventoryNavigator(this.getRootFolder()).searchManagedEntity(VM,
							server.getName());
					model = AssembleTools.getInstance().convertServer(machine);
				}
				return new BsmResult(true, model, "创建虚机成功！");
			} else {
				logger.warn("创建虚机失败！");
				return new BsmResult(false, "创建虚机失败：可能是宿主机的空间资源不够亦或是其他原因导致");
			}
		} catch (Exception e) {
			logger.error("Create Server By Template exception:", e);
			return new BsmResult(false, "虚拟机创建失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	private VirtualDeviceConfigSpec createDiskSpec(String dsName, long diskSizeKB, String diskMode, VirtualMachine vm) {
		VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();
		diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
		diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
		VirtualDisk vd = new VirtualDisk();
		vd.setCapacityInKB(diskSizeKB);
		diskSpec.setDevice(vd);
		vd.setKey(getkey(vm));
		vd.setUnitNumber(getUnitNumber(vm));
		vd.setControllerKey(getcontrollerkey(vm));
		VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
		String diskName = KeyGenerator.uuid();
		String fileName = "[" + dsName + "] " + vm.getName() + "/" + diskName + ".vmdk";
		diskfileBacking.setFileName(fileName);
		diskfileBacking.setDiskMode(diskMode);
		diskfileBacking.setThinProvisioned(true);
		vd.setBacking(diskfileBacking);
		return diskSpec;
	}

	// 获取虚拟机磁盘管理的controlerkey
	private int getcontrollerkey(VirtualMachine vm) {
		int controllerkey = 0;
		if (vm != null) {
			VirtualDevice[] devices = vm.getConfig().getHardware().getDevice();
			if (devices != null && devices.length > 0) {
				for (int i = 0; i < devices.length; i++) {
					VirtualDevice device = devices[i];
					if (device instanceof VirtualDisk) {
						controllerkey = device.getControllerKey();
					}
				}
			}
		}
		return controllerkey;
	}

	// 获取虚拟机已生成key
	private int getkey(VirtualMachine vm) {
		int key = 0;
		if (vm != null) {
			VirtualDevice[] devices = vm.getConfig().getHardware().getDevice();
			if (devices != null && devices.length > 0) {
				for (int i = 0; i < devices.length; i++) {
					VirtualDevice device = devices[i];
					if (device instanceof VirtualDisk) {
						key = device.getKey();
					}
				}
			}
		}
		key = key + 1;
		return key;
	}

	// 获取虚拟机已生成UnitNumber
	private int getUnitNumber(VirtualMachine vm) {
		int UnitNumber = 0;
		if (vm != null) {
			VirtualDevice[] devices = vm.getConfig().getHardware().getDevice();
			if (devices != null && devices.length > 0) {
				for (int i = 0; i < devices.length; i++) {
					VirtualDevice device = devices[i];
					if (device instanceof VirtualDisk) {
						UnitNumber = device.getUnitNumber();
					}
				}
			}
		}
		UnitNumber = UnitNumber + 1;
		return UnitNumber;
	}

	@Override
	public BsmResult start(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			VirtualMachine machine = (VirtualMachine) entity;
			if (machine.getRuntime().getPowerState().equals(VirtualMachinePowerState.poweredOn)) {
				return new BsmResult(true, "开虚拟机已处于开机状态");
			}
			Task task = machine.powerOnVM_Task(null);
			if (task.waitForTask().equals(Task.SUCCESS)) {
				ServerModel serverModel = AssembleTools.getInstance().convertServer(machine);
				return new BsmResult(true, serverModel, "启动虚拟机成功");
			}
			return new BsmResult(false, "启动虚拟机失败");
		} catch (Exception e) {
			logger.error("虚拟机[{}]启动失败！！", instanceId, e);
			return new BsmResult(false, "启动虚拟机失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult stop(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			VirtualMachine machine = (VirtualMachine) entity;
			if (machine.getRuntime().getPowerState().equals(VirtualMachinePowerState.poweredOff)) {
				return new BsmResult(true, "开虚拟机已处于关机状态");
			}
			Task task = machine.powerOffVM_Task();
			if (task.waitForTask().equals(Task.SUCCESS)) {
				return new BsmResult(true, "停止虚拟机成功");
			}
			return new BsmResult(false, "停止虚拟机失败");
		} catch (Exception e) {
			logger.error("虚拟机[{}]停止失败！！", instanceId, e);
			return new BsmResult(false, "虚机停止失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult reboot(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}

			VirtualMachine machine = (VirtualMachine) entity;
			if ("toolsOk".equals(machine.getGuest().getToolsStatus().toString())) {
				machine.rebootGuest();
				return new BsmResult(true, "success", "重启虚拟机成功");
			} else {
				return new BsmResult(false, "tools未就绪，请稍后操作");
			}
		} catch (RemoteException e) {
			logger.error("虚拟机[{}]重启失败！！", instanceId, e);
			return new BsmResult(false, "虚拟机重启失败：该虚拟机可能未运行vmware tools");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult remove(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			VirtualMachine machine = (VirtualMachine) entity;
			Task task = machine.destroy_Task();
			if (task.waitForTask().equals(Task.SUCCESS)) {
				return new BsmResult(true, "删除虚拟机成功");
			}
			return new BsmResult(false, "删除虚拟机失败");
		} catch (Exception e) {
			logger.error("虚拟机[{}]删除失败！！", instanceId, e);
			return new BsmResult(false, "删除虚拟机失败");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult list() {
		try {
			List<ServerModel> serverModels = Lists.newArrayList();
			ManagedEntity[] entities = new InventoryNavigator(this.getRootFolder()).searchManagedEntities(VM);
			if (null == entities || entities.length == 0) {
				logger.info("No VirtualMachine!");
				return new BsmResult(true, serverModels, "success");
			}
			for (ManagedEntity entity : entities) {
				ServerModel serverModel = AssembleTools.getInstance().convertServer((VirtualMachine) entity);
				if (null != serverModel) {
					serverModels.add(serverModel);
				}
			}
			return new BsmResult(true, serverModels, "success");
		} catch (Exception e) {
			logger.error("同步虚机异常！", e);
			return new BsmResult(false, "同步虚机异常！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult detail(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			return new BsmResult(true, AssembleTools.getInstance().convertServer((VirtualMachine) entity), "success");
		} catch (Exception e) {
			logger.error("获取虚机详情异常！", e);
			return new BsmResult(false, "获取虚机详情异常！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult joinSGroup(String serverId, String groupId) {
		return null;
	}

	@Override
	public BsmResult leaveSGroup(String serverId, String groupId) {
		return null;
	}

	@Override
	public BsmResult modify(ServerModel server) {
		try {
			InventoryNavigator navigator = new InventoryNavigator(this.getRootFolder());
			VirtualMachine machine = (VirtualMachine) this.getServiceInstance().getSearchIndex().findByUuid(null,
					server.getInstanceId(), true, true);
			if (null == machine) {
				logger.error("虚拟机不存在！");
				return new BsmResult(false, "编辑虚拟机失败：虚拟机不存在！");
			}
			// 虚拟机配置信息
			VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
			// 设置CPU
			configSpec.setNumCPUs(server.getCpu());
			// 设置内存
			configSpec.setMemoryMB(new Long(server.getMemory()));
			// 设备集合
			List<VirtualDeviceConfigSpec> specs = Lists.newArrayList();
			// 设置磁盘
			if (null != server.getExtendDisk() && server.getExtendDisk() != 0) {
				VirtualDeviceConfigSpec diskSpec = createDiskSpec(server.getDatastore(),
						server.getExtendDisk() * 1024 * 1024, "persistent", machine);
				if (null == diskSpec) {
					logger.error("虚机编辑失败：新增磁盘规格编辑失败！");
					return new BsmResult(false, "编辑虚拟机失败！");
				}
				specs.add(diskSpec);
			}
			// 配置网络设备信息
			operateNetSpec(navigator, server, specs, machine);
			if (!ListTool.isEmpty(specs)) {
				VirtualDeviceConfigSpec[] specArray = new VirtualDeviceConfigSpec[specs.size()];
				configSpec.setDeviceChange(specs.toArray(specArray));
			}
			Task task = machine.reconfigVM_Task(configSpec);
			if (task.waitForTask().equals(Task.SUCCESS)) {
				VirtualMachine entity = (VirtualMachine) this.getServiceInstance().getSearchIndex().findByUuid(null,
						server.getInstanceId(), true, true);
				return new BsmResult(true, AssembleTools.getInstance().convertServer(entity), "虚拟机编辑成功");
			} else {
				String failInfo = "";
				if (null != task.getTaskInfo().getError()) {
					// 返回主机进入维护模式失败的信息
					failInfo = task.getTaskInfo().getError().getLocalizedMessage();
				}
				return new BsmResult(false, "编辑虚机失败   " + failInfo);
			}
		} catch (Exception e) {
			logger.error("Modify server exception:", e);
			return new BsmResult(false, "虚拟机编辑失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult migrate(ServerModel server) {
		String hostName = server.getHostName();
		try {
			ManagedEntity datacenter = new InventoryNavigator(this.getRootFolder()).searchManagedEntity(DC,
					server.getVdcName());
			if (null == datacenter) {
				logger.error("数据中心不存在！");
				return new BsmResult(false, "数据中心不存在！");
			}
			Datacenter center = (Datacenter) datacenter;
			InventoryNavigator navigator = new InventoryNavigator(center);
			VirtualMachine machine = (VirtualMachine) this.getServiceInstance().getSearchIndex().findByUuid(null,
					server.getInstanceId(), true, true);
			if (null == machine) {
				logger.error("虚拟机不存在！");
				return new BsmResult(false, "虚机不存在！");
			}
			// 获取宿主机
			HostSystem hostSystem = (HostSystem) navigator.searchManagedEntity("HostSystem", hostName);
			if (null == hostSystem) {
				logger.error("宿主机不存在！");
				return new BsmResult(false, "迁移虚拟机失败：宿主机不存在！");
			}
			// 获取resourcepool
			ComputeResource resource = null;
			if (StringUtils.isEmpty(server.getClusterName())) {
				resource = (ComputeResource) navigator.searchManagedEntity(CR, hostName);
			} else {
				resource = (ComputeResource) navigator.searchManagedEntity(CR, server.getClusterName());
			}
			VirtualMachinePowerState state = null;
			if (VMStatus.STOPPED.name().equals(server.getStatus())) {
				state = VirtualMachinePowerState.poweredOff;
			} else if (VMStatus.RUNNING.name().equals(server.getStatus())) {
				state = VirtualMachinePowerState.poweredOn;
			} else if (VMStatus.SUSPENDED.name().equals(server.getStatus())) {
				state = VirtualMachinePowerState.suspended;
			}
			Task task = machine.migrateVM_Task(resource.getResourcePool(), hostSystem,
					VirtualMachineMovePriority.defaultPriority, state);
			if (task.waitForTask().equals(Task.SUCCESS)) {
				return new BsmResult(true, "迁移成功!");
			}
			return new BsmResult(false, "迁移失败！");
		} catch (Exception e) {
			logger.error("迁移失败！", e);
			return new BsmResult(false, "迁移失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult OSMigrate(OSMigrateModel OSMigrate) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BsmResult snapshot(SnapshotModel model) {
		try {
			String instanceId = model.getInstanceId();
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			VirtualMachine machine = (VirtualMachine) entity;
			// 原来的快照
			List<SnapshotModel> oldSnapshots = Lists.newArrayList();
			VirtualMachineSnapshotInfo virtualMachineSnapshotInfo = machine.getSnapshot();
			if (null != virtualMachineSnapshotInfo) {
				VirtualMachineSnapshotTree[] trees = virtualMachineSnapshotInfo.getRootSnapshotList();
				AssembleTools.getInstance().traverseSnapshotTree(trees, oldSnapshots);
			}

			Task task = machine.createSnapshot_Task(model.getName(), model.getRemark(), false, false);
			if (task.waitForTask().equals(Task.SUCCESS)) {
				// 返回快照
				List<SnapshotModel> newSnapshots = Lists.newArrayList();
				virtualMachineSnapshotInfo = machine.getSnapshot();
				if (null != virtualMachineSnapshotInfo) {
					VirtualMachineSnapshotTree[] trees = machine.getSnapshot().getRootSnapshotList();
					AssembleTools.getInstance().traverseSnapshotTree(trees, newSnapshots);
				}
				SnapshotModel snapshot = null;
				Map<String, SnapshotModel> snapshots = Maps.newHashMap();
				for (SnapshotModel snapshotModel : oldSnapshots) {
					snapshots.put(snapshotModel.getSnapshotVal(), snapshotModel);
				}
				for (SnapshotModel snapshotModel : newSnapshots) {
					if (!snapshots.containsKey(snapshotModel.getSnapshotVal())) {
						snapshot = snapshotModel;
						break;
					}
				}
				return new BsmResult(true, snapshot, "创建快照成功!");
			}
			return new BsmResult(false, "创建快照失败！");
		} catch (Exception e) {
			logger.error("创建快照失败！", e);
			return new BsmResult(false, "创建快照失败！");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult suspend(String instanceId) {
		try {
			ManagedEntity entity = this.getServiceInstance().getSearchIndex().findByUuid(null, instanceId, true, true);
			if (null == entity) {
				logger.error("虚拟机[{}] 不存在！", instanceId);
				return new BsmResult(false, "虚机不存在！");
			}
			VirtualMachine machine = (VirtualMachine) entity;
			if (machine.getRuntime().getPowerState().equals(VirtualMachinePowerState.suspended)) {
				return new BsmResult(true, "虚拟机已经处于挂起状态");
			}
			Task task = machine.suspendVM_Task();
			if (task.waitForTask().equals(Task.SUCCESS)) {
				ServerModel serverModel = AssembleTools.getInstance().convertServer(machine);
				return new BsmResult(true, serverModel, "挂起虚拟机成功");
			}
			return new BsmResult(false, "挂起虚拟机失败");
		} catch (Exception e) {
			logger.error("虚拟机[{}]挂起失败！！", instanceId, e);
			return new BsmResult(false, "挂起虚拟机失败");
		} finally {
			this.getServiceInstance().getServerConnection().logout();
		}
	}

	@Override
	public BsmResult VncConsole(String vncType, String serverId) {
		// TODO Auto-generated method stub
		return null;
	}

	private VirtualDeviceConfigSpec addNetSpec(String uuid, String key, VirtualMachine machine, String type,
			ManagedObjectReference network, String category) {
		VirtualDeviceConfigSpec netSpec = new VirtualDeviceConfigSpec();
		netSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
		VirtualEthernetCard vd = null;
		if ("E1000".equals(type)) {
			vd = new VirtualE1000();
		} else if ("VMXNET2".equals(type)) {
			vd = new VirtualVmxnet2();
		} else if ("VMXNET3".equals(type)) {
			vd = new VirtualVmxnet3();
		} else if ("E1000E".equals(type)) {
			vd = new VirtualE1000e();
		} else {
			vd = new VirtualPCNet32();
		}
		if (category.equals("VSWITCH")) {
			VirtualEthernetCardNetworkBackingInfo netBackInfo = new VirtualEthernetCardNetworkBackingInfo();
			netBackInfo.setDeviceName(key);
			vd.setBacking(netBackInfo);
		} else {
			DistributedVirtualSwitchPortConnection portCon = new DistributedVirtualSwitchPortConnection();
			portCon.setSwitchUuid(uuid);
			portCon.setPortgroupKey(key);
			VirtualEthernetCardDistributedVirtualPortBackingInfo portBackingInfo = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
			portBackingInfo.setPort(portCon);
			vd.setBacking(portBackingInfo);
		}
		vd.setKey(getkey(machine));
		vd.setAddressType("generated");
		netSpec.setDevice(vd);
		return netSpec;
	}

	private VirtualDeviceConfigSpec removeNetSpec(VirtualDevice device) {
		VirtualDeviceConfigSpec netSpec = new VirtualDeviceConfigSpec();
		netSpec.setOperation(VirtualDeviceConfigSpecOperation.remove);
		VirtualEthernetCard vd = new VirtualEthernetCard();
		vd.setKey(device.getKey());
		netSpec.setDevice(vd);
		return netSpec;
	}

	private VirtualDeviceConfigSpec editNetSpec(String uuid, String key, VirtualDevice device, String category) {
		VirtualDeviceConfigSpec netSpec = new VirtualDeviceConfigSpec();
		netSpec.setOperation(VirtualDeviceConfigSpecOperation.edit);
		if (category.equals("VSWITCH")) {
			VirtualEthernetCardNetworkBackingInfo netBackInfo = new VirtualEthernetCardNetworkBackingInfo();
			netBackInfo.setDeviceName(key);
			device.setBacking(netBackInfo);
		} else {
			DistributedVirtualSwitchPortConnection portCon = new DistributedVirtualSwitchPortConnection();
			portCon.setSwitchUuid(uuid);
			portCon.setPortgroupKey(key);
			VirtualEthernetCardDistributedVirtualPortBackingInfo portBackingInfo = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
			portBackingInfo.setPort(portCon);
			device.setBacking(portBackingInfo);
		}
		netSpec.setDevice(device);
		return netSpec;
	}

	private void operateNetSpec(InventoryNavigator navigator, ServerModel server, List<VirtualDeviceConfigSpec> specs,
			VirtualMachine machine) throws Exception {
		// 网络信息
		VirtualDevice[] devices = machine.getConfig().getHardware().getDevice();
		Map<String, VirtualDevice> deviceMap = Maps.newHashMap();
		if (null != devices) {
			for (VirtualDevice device : devices) {
				deviceMap.put(device.getDeviceInfo().getLabel(), device);
			}
		}
		Datacenter datacenter = (Datacenter) navigator.searchManagedEntity(DC, server.getVdcName());
		ManagedEntity[] networks = datacenter.getNetworkFolder().getChildEntity();
		Map<String, String> uuidMap = Maps.newHashMap();
		Map<String, String> portMap = Maps.newHashMap();
		Map<String, ManagedObjectReference> networkMap = Maps.newHashMap();
		for (ManagedEntity network : networks) {
			if (network instanceof Network && !(network instanceof DistributedVirtualPortgroup)) {
				networkMap.put(network.getName(), network.getMOR());
			} else if (network instanceof VmwareDistributedVirtualSwitch) {
				String uuid = ((VmwareDistributedVirtualSwitch) network).getUuid();
				DistributedVirtualPortgroup[] portgroups = ((VmwareDistributedVirtualSwitch) network).getPortgroup();
				for (DistributedVirtualPortgroup portgroup : portgroups) {
					portMap.put(portgroup.getName(), portgroup.getKey());
					uuidMap.put(portgroup.getName(), uuid);
				}
			}
		}
		List<NetcardOperation> operations = server.getOperations();
		if (!ListTool.isEmpty(operations)) {
			for (NetcardOperation operation : operations) {
				String operate = operation.getOperation();
				if ("ADD".equals(operate)) {
					String name = operation.getName();
					if (networkMap.containsKey(name)) {
						specs.add(
								addNetSpec(null, name, machine, operation.getType(), networkMap.get(name), "VSWITCH"));
					} else {
						specs.add(addNetSpec(uuidMap.get(name), portMap.get(name), machine, operation.getType(), null,
								"DVSWITCH"));
					}
				} else if ("REMOVE".equals(operate) && deviceMap.containsKey(operation.getLabel())) {
					specs.add(removeNetSpec(deviceMap.get(operation.getLabel())));
				} else if ("EDIT".equals(operate) && deviceMap.containsKey(operation.getLabel())) {
					String name = operation.getName();
					if (networkMap.containsKey(name)) {
						specs.add(editNetSpec(null, name, deviceMap.get(operation.getLabel()), "VSWITCH"));
					} else {
						specs.add(editNetSpec(uuidMap.get(name), portMap.get(name), deviceMap.get(operation.getLabel()),
								"DVSWITCH"));
					}
				}
			}
		}
	}

    @Override
    public BsmResult resume(String instanceId) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BsmResult unpause(String instanceId) {
        // TODO Auto-generated method stub
        return null;
    }

}
